library(plotly)
Registered S3 method overwritten by 'data.table':
method from
print.data.table
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
beds <- read_csv("raw_data/non_covid_raw_data/beds_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()
Warning: One or more parsing issues, see `problems()` for detailsRows: 30458 Columns: 20── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (10): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, Specialty, SpecialtyQF, SpecialtyName, SpecialtyNameQF
dbl (5): AllStaffedBeddays, TotalOccupiedBeddays, AverageAvailableStaffedBeds, AverageOccupiedBeds, PercentageOccupancy
lgl (5): AllStaffedBeddaysQF, TotalOccupiedBeddaysQF, AverageAvailableStaffedBedsQF, AverageOccupiedBedsQF, PercentageOcc...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
beds %>%
filter(specialty_name == "All Acute") %>%
ggplot(aes(x = quarter, y = percentage_occupancy))+
geom_line(aes(colour = hb), group = 1)+
facet_wrap(~ hb)

library(lubridate)
Attaching package: ‘lubridate’
The following objects are masked from ‘package:base’:
date, intersect, setdiff, union
library(zoo)
# change quarter column into the date at the start of each quarter
age_sex <- age_sex %>%
mutate(quarter = yq(quarter))
# shows the total length of stay by age bracket for emergency inpatients
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(total_length_of_stay = sum(length_of_stay)) %>%
ggplot(aes(x = quarter, y = total_length_of_stay))+
geom_line(aes(colour = age))+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(total_length_of_stay = sum(length_of_stay)) %>%
ggplot(aes(x = quarter, y = total_length_of_stay))+
geom_line(aes(colour = age))+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# shows the mean length of stay by age bracket for elective inpatients
# can facet by sex
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_col(aes(fill = age), position = "dodge")+
theme(axis.text.x = element_text(angle = 45))+
scale_x_date(breaks = 4)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.Error: Invalid input: date_trans works with objects of class Date only

age_sex %>%
mutate(date = yq(quarter),
year = year(date),
month = month(date, label = TRUE, abbr = FALSE),
season = case_when(
str_detect(month, "December") ~ "Winter",
str_detect(month, "January") ~ "Winter",
str_detect(month, "February") ~ "Winter",
str_detect(month, "March") ~ "Spring",
str_detect(month, "April") ~ "Spring",
str_detect(month, "May") ~ "Spring",
str_detect(month, "June") ~ "Summer",
str_detect(month, "July") ~ "Summer",
str_detect(month, "August") ~ "Summer",
str_detect(month, "September") ~ "Autumn",
str_detect(month, "October") ~ "Autumn",
str_detect(month, "November") ~ "Autumn"),
season = factor(season, order = TRUE))
Warning: All formats failed to parse. No formats found.
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, sex) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = sex, group = sex))+
theme(axis.text.x = element_text(angle = 45))+
geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = sex), size = 0.5)+
labs(title = "Emergency Inpatient by gender and average length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, sex) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = sex, group = sex))+
theme(axis.text.x = element_text(angle = 45))+
geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = sex), size = 0.5)+
labs(title = "Elective Inpatient by gender and average length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg length of stay
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Emergency inpatient by age and avg length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# elective inpatient by age and avg length of stay
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Elective inpatient by age and avg length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg episodes
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_episodes))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Emergency inpatient by age and avg episodes")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg episodes
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_episodes))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Emergency inpatient by age and avg episodes")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>%
filter(admission_type %in% c("Emergency Inpatients", "Elective Inpatients")) %>%
group_by(quarter, admission_type) %>%
summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stay, colour = admission_type))+
geom_line(aes(group = admission_type))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.


simd <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_simd.csv") %>% janitor::clean_names()
Rows: 40821 Columns: 18── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, SIMDQF, AverageLengthOfEpisodeQF, AverageLengthO...
dbl (7): SIMD, Episodes, LengthOfEpisode, AverageLengthOfEpisode, Stays, LengthOfStay, AverageLengthOfStay
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#total episodes(hospitalisations?) by simd value
simd %>%
drop_na(simd) %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(total_episodes = sum(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = total_episodes, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# plot avg stay length for most and least deprived
simd %>%
filter(simd %in% c(1,5)) %>%
drop_na(simd) %>%
group_by(quarter,simd) %>%
summarise(avg_stay_length = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stay_length)) +
geom_line(aes(colour = simd, group = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

speciality <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()
Rows: 95270 Columns: 18── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (12): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, Specialty, SpecialtyName, AverageLengthOfEpisode...
dbl (6): Episodes, LengthOfEpisode, AverageLengthOfEpisode, Spells, LengthOfSpell, AverageLengthOfSpell
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

ae_wait_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% janitor::clean_names()
glimpse(ae_wait_times)
#make a date and year column with the first date of every month
ae_wait_times <- ae_wait_times %>%
mutate(date = ym(month), .after = month,
year = year(date))
#make a percent column with percent of patients meeting the 4hr target time
ae_wait_times <- ae_wait_times %>%
mutate(percent_4hr_target_achieved = (number_meeting_target_aggregate/number_of_attendances_aggregate)*100) %>%
#add an 8hr one - not currently used
mutate(percent_seen_within_8hr = ((number_of_attendances_aggregate-attendance_greater8hrs)/number_of_attendances_aggregate)*100)
ggplotly(for_plotly)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
Warning: `gather_()` was deprecated in tidyr 1.2.0.
Please use `gather()` instead.

target_2018 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2018) %>%
rename(ae_target_2018 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2018)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.


LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShwbG90bHkpDQpgYGANCg0KYGBge3J9DQpiZWRzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvYmVkc19ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zcGVjaWFsdHkuY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCmBgYA0KDQpgYGB7cn0NCmJlZHMgJT4lIA0KICBmaWx0ZXIoc3BlY2lhbHR5X25hbWUgPT0gIkFsbCBBY3V0ZSIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gaGIpLCBncm91cCA9IDEpKw0KICBmYWNldF93cmFwKH4gaGIpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KYGBge3J9DQphZ2Vfc2V4IDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaW5wYXRpZW50X2FuZF9kYXljYXNlX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYWdlX2FuZF9zZXguY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KaGVhbHRoX2JvYXJkX25hbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaGVhbHRoX2JvYXJkX25hbWVzLmNzdiIpDQoNCmFnZV9zZXggJT4lIA0KICBjb3VudChoYikNCg0Kc2Vhc29uX2FnZV9zZXggPC0gYWdlX3NleCAlPiUgDQogIG11dGF0ZShkYXRlID0geXEocXVhcnRlciksDQogICAgICAgICB5ZWFyID0geWVhcihkYXRlKSwNCiAgICAgICAgIG1vbnRoID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpLA0KICAgICAgICAgc2Vhc29uID0gY2FzZV93aGVuKA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiRGVjZW1iZXIiKSB+ICJXaW50ZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSmFudWFyeSIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJGZWJydWFyeSIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJNYXJjaCIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJBcHJpbCIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJNYXkiKSB+ICJTcHJpbmciLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSnVuZSIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKdWx5IikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkF1Z3VzdCIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJTZXB0ZW1iZXIiKSB+ICJBdXR1bW4iLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiT2N0b2JlciIpIH4gIkF1dHVtbiIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJOb3ZlbWJlciIpIH4gIkF1dHVtbiIpLA0KICAgICAgICAgc2Vhc29uID0gZmFjdG9yKHNlYXNvbiwgb3JkZXIgPSBUUlVFKSkgDQpgYGANCmBgYHtyfQ0KDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoem9vKQ0KDQojIGNoYW5nZSBxdWFydGVyIGNvbHVtbiBpbnRvIHRoZSBkYXRlIGF0IHRoZSBzdGFydCBvZiBlYWNoIHF1YXJ0ZXINCiBhZ2Vfc2V4IDwtICBhZ2Vfc2V4ICU+JSANCiAgICBtdXRhdGUocXVhcnRlciA9IHlxKHF1YXJ0ZXIpKQ0KDQogIyBzaG93cyB0aGUgdG90YWwgbGVuZ3RoIG9mIHN0YXkgYnkgYWdlIGJyYWNrZXQgZm9yIGVtZXJnZW5jeSBpbnBhdGllbnRzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9sZW5ndGhfb2Zfc3RheSA9IHN1bShsZW5ndGhfb2Zfc3RheSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyfQ0KYWdlX3NleCAlPiUgDQpjb3VudChhZG1pc3Npb25fdHlwZSkNCg0KYWdlX3NleA0KYGBgDQoNCmBgYHtyfQ0KICMgc2hvd3MgdGhlIHRvdGFsIGxlbmd0aCBvZiBzdGF5IGJ5IGFnZSBicmFja2V0IGZvciBlbGVjdGl2ZSBpbnBhdGllbnRzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbGVjdGl2ZSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2xlbmd0aF9vZl9zdGF5ID0gc3VtKGxlbmd0aF9vZl9zdGF5KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdG90YWxfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpDQpgYGANCg0KYGBge3J9DQogIyBzaG93cyB0aGUgbWVhbiBsZW5ndGggb2Ygc3RheSBieSBhZ2UgYnJhY2tldCBmb3IgZW1lcmdlbmN5IGlucGF0aWVudHMNCiNjYW4gZmFjZXQgYnkgc2V4IGFsc28gaWYgcmVxdWlyZWQNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2Zfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KICAjZmFjZXRfd3JhcCggfiBzZXgpDQoNCiAjIHNob3dzIHRoZSBtZWFuIGxlbmd0aCBvZiBzdGF5IGJ5IGFnZSBicmFja2V0IGZvciBlbGVjdGl2ZSBpbnBhdGllbnRzDQojIGNhbiBmYWNldCBieSBzZXggDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbGVjdGl2ZSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2Zfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fY29sKGFlcyhmaWxsID0gYWdlKSwgcG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICBzY2FsZV94X2RhdGUoYnJlYWtzID0gNCkNCiAgI2ZhY2V0X3dyYXAofiBzZXgpDQpgYGANCg0KYGBge3J9DQphZ2Vfc2V4ICU+JSANCiAgbXV0YXRlKGRhdGUgPSB5cShxdWFydGVyKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpLA0KICAgICAgICAgbW9udGggPSBtb250aChkYXRlLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBGQUxTRSksDQogICAgICAgICBzZWFzb24gPSBjYXNlX3doZW4oDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJEZWNlbWJlciIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKYW51YXJ5IikgfiAiV2ludGVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkZlYnJ1YXJ5IikgfiAiV2ludGVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk1hcmNoIikgfiAiU3ByaW5nIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkFwcmlsIikgfiAiU3ByaW5nIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk1heSIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKdW5lIikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkp1bHkiKSB+ICJTdW1tZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiQXVndXN0IikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIlNlcHRlbWJlciIpIH4gIkF1dHVtbiIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJPY3RvYmVyIikgfiAiQXV0dW1uIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk5vdmVtYmVyIikgfiAiQXV0dW1uIiksDQogICAgICAgICBzZWFzb24gPSBmYWN0b3Ioc2Vhc29uLCBvcmRlciA9IFRSVUUpKSANCmBgYA0KDQoNCmBgYHtyfQ0KDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgc2V4KSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICBnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzZXgpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgSW5wYXRpZW50IGJ5IGdlbmRlciBhbmQgYXZlcmFnZSBsZW5ndGggb2Ygc3RheSIpDQoNCg0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRWxlY3RpdmUgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgc2V4KSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICBnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzZXgpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbGVjdGl2ZSBJbnBhdGllbnQgYnkgZ2VuZGVyIGFuZCBhdmVyYWdlIGxlbmd0aCBvZiBzdGF5IikNCg0KYGBgDQoNCg0KYGBge3J9DQojIGVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIHN0YXkNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2Zfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGxlbmd0aCBvZiBzdGF5IikNCg0KIyBlbGVjdGl2ZSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIHN0YXkNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVsZWN0aXZlIElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UsIGdyb3VwID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSsNCiAgI2dlb21fc21vb3RoKGFlcyhjb2xvdXIgPSBzZXgsIGdyb3VwID0gc2V4KSwgc2UgPSBGQUxTRSkrDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGFnZSksIHNpemUgPSAwLjUpKw0KICBsYWJzKHRpdGxlID0gIkVsZWN0aXZlIGlucGF0aWVudCBieSBhZ2UgYW5kIGF2ZyBsZW5ndGggb2Ygc3RheSIpDQpgYGANCmBgYHtyfQ0KIyBlbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGVwaXNvZGVzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfZXBpc29kZXMgPSBtZWFuKGVwaXNvZGVzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfZXBpc29kZXMpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UsIGdyb3VwID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSsNCiAgI2dlb21fc21vb3RoKGFlcyhjb2xvdXIgPSBzZXgsIGdyb3VwID0gc2V4KSwgc2UgPSBGQUxTRSkrDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGFnZSksIHNpemUgPSAwLjUpKw0KICBsYWJzKHRpdGxlID0gIkVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgZXBpc29kZXMiKQ0KDQojIGVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgZXBpc29kZXMNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVsZWN0aXZlIElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2VwaXNvZGVzID0gbWVhbihlcGlzb2RlcywgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2VwaXNvZGVzKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGVwaXNvZGVzIikNCmBgYA0KDQoNCg0KYGBge3J9DQojIFBsb3QgY29tcGFyaXNvbiBvZiBFbWVyZ2VuY3kgdnMgRWxlY3RpdmUgc3VibWlzc2lvbnMNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgJWluJSBjKCJFbWVyZ2VuY3kgSW5wYXRpZW50cyIsICJFbGVjdGl2ZSBJbnBhdGllbnRzIikpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfc3RheSwgY29sb3VyID0gYWRtaXNzaW9uX3R5cGUpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGFkbWlzc2lvbl90eXBlKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCg0KYGBge3J9DQojIGF2Z19zdGF5IGJ5IGFkbWlzc2lvbiB0eXBlDQphZ2Vfc2V4ICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfc3RheSwgY29sb3VyID0gYWRtaXNzaW9uX3R5cGUpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGFkbWlzc2lvbl90eXBlKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KDQojIGF2Z19zdGF5IGZvciBhbGwgdHlwZXMNCmFnZV9zZXggJT4lIA0KICBncm91cF9ieShxdWFydGVyKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX3N0YXksIGdyb3VwID0gMSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gMSkpKw0KICBnZW9tX3BvaW50KCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCiMgbnVtYmVyIG9mIHN0YXlzIGZvciBhbGwgdHlwZXMNCmFnZV9zZXggJT4lIA0KICBncm91cF9ieShxdWFydGVyKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9zdGF5cyA9IHN1bShzdGF5cywgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdG90YWxfc3RheXMsIGdyb3VwID0gMSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gMSkpKw0KICBnZW9tX3BvaW50KCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQpgYGB7cn0NCnNpbWQgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9pbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc2ltZC5jc3YiKSAlPiUgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KYGBgDQpgYGB7cn0NCiN0b3RhbCBlcGlzb2Rlcyhob3NwaXRhbGlzYXRpb25zPykgYnkgc2ltZCB2YWx1ZQ0Kc2ltZCAlPiUgDQogIGRyb3BfbmEoc2ltZCkgJT4lDQogIG11dGF0ZShzaW1kID0gYXMuZmFjdG9yKHNpbWQpKSAlPiUgIyBnaXZlcyBlYWNoIHNpbWQgYSBzZXBhcmF0ZSBjb2xvdXINCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfZXBpc29kZXMgPSBzdW0oZXBpc29kZXMsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2VwaXNvZGVzLCBncm91cCA9IHNpbWQpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzaW1kKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkNCiAgDQogIA0KYGBgDQoNCg0KYGBge3J9DQojIHBsb3QgYXZnIHN0YXkgbGVuZ3RoIGZvciBtb3N0IGFuZCBsZWFzdCBkZXByaXZlZCBmb3IgZW1lcmdlbmN5IHVucGF0aWVudHMNCnNpbWQgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIiwgc2ltZCAlaW4lIGMoMSw1KSkgJT4lIA0KICBkcm9wX25hKHNpbWQpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcixzaW1kKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfc3RheV9sZW5ndGggPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19zdGF5X2xlbmd0aCkpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzaW1kLCBncm91cCA9IHNpbWQpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQpgYGANCg0KDQpgYGB7cn0NCnNwZWNpYWxpdHkgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9pbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc3BlY2lhbHR5LmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQpgYGANCg0KYGBge3J9DQpzcGVjaWFsaXR5ICU+JSANCiAgY291bnQoYWRtaXNzaW9uX3R5cGUpDQoNCnNwZWNpYWxpdHkgJT4lIA0KICBjb3VudChoYikNCg0Kc3BlY2lhbGl0eSAlPiUgDQogIGNvdW50KGxvY2F0aW9uKQ0KDQpzcGVjaWFsaXR5ICU+JSANCiAgY291bnQoc3BlY2lhbHR5X25hbWUpDQoNCiMgYWRkIGF2ZXJhZ2VzIA0Kc3BlY2lhbGl0eV9hdmVyYWdlcyA8LSBzcGVjaWFsaXR5ICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgbXV0YXRlKGF2Z19sZW5ndGhfc3BlbGw9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3BlbGwsIG5hLnJtID0gVFJVRSksDQogICAgICAgICBhdmdfbGVuZ3RoX2VwaXNvZGUgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgdW5ncm91cCgpDQoNCg0Kc3BlY2lhbGl0eV9hdmVyYWdlcyAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIHNsaWNlKDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUsIGdyb3VwID0gYWRtaXNzaW9uX3R5cGUpKSArIA0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQpgYGB7cn0NCmFlX3dhaXRfdGltZXMgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9tb250aGx5X2FlX3dhaXRpbmd0aW1lc18yMDIyMDYuY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KZ2xpbXBzZShhZV93YWl0X3RpbWVzKQ0KDQojbWFrZSBhIGRhdGUgYW5kIHllYXIgY29sdW1uIHdpdGggdGhlIGZpcnN0IGRhdGUgb2YgZXZlcnkgbW9udGgNCmFlX3dhaXRfdGltZXMgPC0gYWVfd2FpdF90aW1lcyAlPiUgDQogIG11dGF0ZShkYXRlID0geW0obW9udGgpLCAuYWZ0ZXIgPSBtb250aCwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKQ0KDQojbWFrZSBhIHBlcmNlbnQgY29sdW1uIHdpdGggcGVyY2VudCBvZiBwYXRpZW50cyBtZWV0aW5nIHRoZSA0aHIgdGFyZ2V0IHRpbWUNCmFlX3dhaXRfdGltZXMgPC0gYWVfd2FpdF90aW1lcyAlPiUgDQogIG11dGF0ZShwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQgPSAobnVtYmVyX21lZXRpbmdfdGFyZ2V0X2FnZ3JlZ2F0ZS9udW1iZXJfb2ZfYXR0ZW5kYW5jZXNfYWdncmVnYXRlKSoxMDApICU+JSANCiAgI2FkZCBhbiA4aHIgb25lIC0gbm90IGN1cnJlbnRseSB1c2VkDQptdXRhdGUocGVyY2VudF9zZWVuX3dpdGhpbl84aHIgPSAoKG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUtYXR0ZW5kYW5jZV9ncmVhdGVyOGhycykvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkqMTAwKQ0KYGBgDQoNCg0KYGBge3J9DQojIGRyYXcgcGVyY2VudGFnZSBvZiA0IGhvdXIgd2FpdCBmb3IgYWxsIHllYXJzDQpmb3JfcGxvdGx5IDwtIGFlX3dhaXRfdGltZXMgJT4lIA0KICBmaWx0ZXIoZGVwYXJ0bWVudF90eXBlID09ICJFbWVyZ2VuY3kgRGVwYXJ0bWVudCIpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZSwgZGVwYXJ0bWVudF90eXBlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfNGhyX3RhcmdldF9tYWRlID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSBhdmdfNGhyX3RhcmdldF9tYWRlKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gZGVwYXJ0bWVudF90eXBlKSkrDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI2IG1vbnRocyIsIGRhdGVfbGFiZWxzID0gICIlYiAlWSIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSsNCiAgZ2VvbV9zbW9vdGgoKSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEzLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE1LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgbGFicyh0aXRsZSA9ICJwZXJjZW50YWdlIG9mIEEmRSBkZXBhcnRtZW50cyBtZWV0aW5nIHRoZSA0IGhyIHRhcmdldCB0dXJuYXJvdW5kIGZvciBwYXRpZW50cyIsDQogICAgICAgc3VidGl0bGUgPSAiYWRkZWQgaW4gdmVydGljYWwgbGluZXMgZm9yIEphbnVhcnkgdG8gaGVscCIpDQoNCmdncGxvdGx5KGZvcl9wbG90bHkpDQpgYGANCg0KYGBge3J9DQojIDRociB3YWl0IGJ5IGhlYWx0aCBib2FyZCBmb3IgYWxsIHllYXJzIGZhY2V0IHdyYXBwZWQNCmFlX3dhaXRfdGltZXMgJT4lIA0KICBmaWx0ZXIoZGVwYXJ0bWVudF90eXBlID09ICJFbWVyZ2VuY3kgRGVwYXJ0bWVudCIpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZSwgaGJ0KSAlPiUgDQogIG11dGF0ZShhdmdfNGhyX3RhcmdldF9tYWRlID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQpKSAlPiUgDQogIHNsaWNlKDEpICU+JSAgDQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSBhdmdfNGhyX3RhcmdldF9tYWRlKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gaGJ0KSkrDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI2IG1vbnRocyIsIGRhdGVfbGFiZWxzID0gICIlYiAlWSIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSsNCiAgZ2VvbV9zbW9vdGgoKSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEzLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE1LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZmFjZXRfd3JhcCh+IGhidCkNCmBgYA0KDQpgYGB7cn0NCnRhcmdldF8yMDA3IDwtIGFlX3dhaXRfdGltZXMgJT4lDQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIA0KICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID09IDIwMDcpICU+JSANCiAgcmVuYW1lKGFlX3RhcmdldF8yMDA3ID0gYWVfNGhyX3RhcmdldF9hY2hpZXZlZCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDA3KQ0KDQp0YXJnZXRfMjAxOCA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDE4KSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAxOCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAxOCkNCg0KYGBgDQoNCg0KDQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoc2YpDQoNCnNjb3RsYW5kIDwtIHN0X3JlYWQoIi4uLy4uLy4uLy4uL0Rvd25sb2Fkcy9TR19OSFNfSGVhbHRoQm9hcmRzXzIwMTkvU0dfTkhTX0hlYWx0aEJvYXJkc18yMDE5LnNocCIpDQoNCiMgdmlldyhzY290bGFuZCkNCiMgDQpoZWFkKHNjb3RsYW5kLCAzKQ0KIyANCnBsb3Qoc2NvdGxhbmRbLTFdKQ0KDQpzY290bGFuZCA8LSAgc2NvdGxhbmQgJT4lIA0KICBtdXRhdGUoY2VudHJlcyA9IHN0X2NlbnRyb2lkKHN0X21ha2VfdmFsaWQoZ2VvbWV0cnkpKSkgJT4lDQogICAgbXV0YXRlKGxhdCA9IHN0X2Nvb3JkaW5hdGVzKGNlbnRyZXMpWywxXSwNCiAgICAgICAgICAgbG9uZyA9IHN0X2Nvb3JkaW5hdGVzKGNlbnRyZXMpWywyXSwNCiAgICAgICAgICAgdGFyZ2V0XzIwMDcgPSB0YXJnZXRfMjAwNyRhZV90YXJnZXRfMjAwNywNCiAgICAgICAgICAgdGFyZ2V0XzIwMTggPSB0YXJnZXRfMjAxOCRhZV90YXJnZXRfMjAxOCwNCiAgICAgICAgICAgY2hhbmdlX2FlID0gdGFyZ2V0XzIwMDcgLSB0YXJnZXRfMjAxOCkNCg0KZ2dwbG90KGRhdGEgPSBzY290bGFuZCkgKw0KICAgIGdlb21fc2YoYWVzKGZpbGwgPSBjaGFuZ2VfYWUpKSArDQogICAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIpKw0KICBsYWJzKHRpdGxlID0gInBlcmNlbnQgY2hhbmdlIGluIEEmRSBkZXB0cyBtZWV0aW5nIHRoZSA0IGhvdXIgdGFyZ2V0IDIwMDcgLSAyMDE4IikNCiAgDQoNCmdncGxvdChkYXRhID0gc2NvdGxhbmQpICsNCiAgICBnZW9tX3NmKGFlcyhmaWxsID0gdGFyZ2V0XzIwMTgpKSArDQogICAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIpKw0KICBsYWJzKHRpdGxlID0gIlBlcmNlbnQgb2YgQSZFIGRlcHRzIG1ha2luZyB0aGUgNGhyIHRhcmdldCIpDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gc2NvdGxhbmQpICsNCmdlb21fc2YoZmlsbCA9ICJncmVlbiIpKw0KZ2dyZXBlbDo6Z2VvbV90ZXh0X3JlcGVsKGFlcyh4ID0gbGF0ICwgeSA9IGxvbmcsIGxhYmVsID0gcGFzdGUoSEJDb2RlLCBIQk5hbWUsIHNlcCA9ICJcbiIpKSwgbWluLnNlZ21lbnQubGVuZ3RoID0gMC4wNSxzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICB0aGVtZV92b2lkKCkNCmBgYA0KYGBge3J9DQoNCmxpYnJhcnkoc2YpDQoNCnNjb3RsYW5kX3NtYWxsZXIgPC0gc2NvdGxhbmQgJT4lICMgbWFrZSBhIHNtYWxsZXIgdmVyc2lvbiBmb3IgcGVyZm9ybWFuY2UgaXNzdWVzDQogIHN0X3NpbXBsaWZ5KFRSVUUsIGRUb2xlcmFuY2UgPSAyMDAwKQ0KI2ZpeGVzIHByb2JsZW1zIGNhdXNlZCBieSBhYm92ZSANCnNjb3RsYW5kX3NtYWxsZXIgPC0gc2Y6OnN0X2Nhc3Qoc2NvdGxhbmRfc21hbGxlciwgIk1VTFRJUE9MWUdPTiIpDQoNCg0KIyANCiMgICBmaWcgPC0gZ2dwbG90bHkoDQojICAgICBnZ3Bsb3Qoc2NvdGxhbmQpKw0KIyAgIGdlb21fc2YoYWVzKGZpbGwgPSBIQk5hbWUpKQ0KIyApDQojICAgZmlnDQoNCiAgDQogIHAgPC0gZ2dwbG90KHNjb3RsYW5kX3NtYWxsZXIpICsgDQogIGdlb21fc2YoYWVzKGZpbGwgPSBIQk5hbWUsIHRleHQgPSBwYXN0ZSgiPGI+IiwgSEJOYW1lLCAiPC9iPlxuIiwgSEJDb2RlKSkpKw0KICAgIHRoZW1lX3ZvaWQoKQ0KICBwICU+JQ0KICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUNCiAgc3R5bGUoaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIpLCBob3Zlcm9uID0gImZpbGwiKQ0KICAgIA0KICANCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZGFzaCkNCmBgYA0KDQo=